<?php

namespace App\Tyt\Manager\Wechat;


use App\Models\Customer\Customer;
use App\Models\Customer\CustomerInfo;
use App\Models\Order\Order;
use App\Models\Wechat;
use App\Tyt\Service\Wechat\WechatInterface;
use App\User;
use EasyWeChat\Factory;

class WechatManager implements WechatInterface
{

    protected $app;

    protected $session;

    protected $encryptedData;

    private $config;

    public function __construct(Wechat $config, ?array $encryptedData = [])
    {
        $this->encryptedData = $encryptedData;
        $this->config = $config;
    }

    /**
     * 初始化配置
     */
    public function init()
    {
        $this->miniProgram();
    }

    /**
     * 根据code获取登录信息
     * @param string $code
     * @return array
     */
    public function oauth(?string $code = null): WechatInterface
    {
        $this->session = $this->app->auth->session($code ?? $this->encryptedData['code']);
        return $this;
    }

    private function miniProgram()
    {
        $config = [
            'app_id'        => $this->config->app_id,
            'secret'        => $this->config->secret,

            // 下面为可选项
            // 指定 API 调用返回结果的类型：array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];
        $this->app = Factory::miniProgram($config);
    }

    public function payment()
    {
        $config = [
            // 必要配置
            'app_id' => $this->config->app_id,
            'mch_id' => $this->config->mch_id,
            'key'    => $this->config->mch_key,   // API 密钥

            'sandbox' => env('SANDBOX_TYPE', false), // 设置为 false 或注释则关闭沙箱模式

            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
//            'cert_path' => 'path/to/your/cert.pem', // XXX: 绝对路径！！！！
//            'key_path'  => 'path/to/your/key',      // XXX: 绝对路径！！！！

        ];
        $this->app = Factory::payment($config);
        return $this;
    }

    public function unify(Order $order)
    {
        $customer = \Auth::user();
        $result = $this->app->order->unify([
            'body'             => '视频购买-消费',
            'out_trade_no'     => $order->number,
            'total_fee'        => $order->total * 100,
            'spbill_create_ip' => '', // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
            'notify_url'       => route('nodify'), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type'       => 'JSAPI',
            'openid'           => $customer->openid,
        ]);
        return $result;
    }

    public function notify()
    {
        $response = $this->app->handlePaidNotify(function ($message, $fail) {
            $order = Order::where('number', $message['out_trade_no'])->first();
            if (!$order || $order->state === Order::ORDER_PAY) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                // 用户是否支付成功
                if (array_get($message, 'result_code') === 'SUCCESS') {
                    $order->state = Order::ORDER_PAY;

                    // 用户支付失败
                } elseif (array_get($message, 'result_code') === 'FAIL') {
                    $order->state = 'fail';
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
            $order->save();
            return true;
        });
        \Log::debug('notify', ['data' => $response]);
        return $response;
    }

    /**
     * 获取用户信息
     */
    public function getData(): array
    {
        return $this->getUserInfo();
    }

    /**
     * 生成新用户
     */
    public function save(): Customer
    {
        $userInfo = $this->getUserInfo();
        $customer = Customer::firstOrCreate(['openid' => $userInfo['openId']]);
        \Log::debug('data', ['dat' => $userInfo]);
        if (!$customer->info) {
            \DB::transaction(function () use ($userInfo, $customer) {
                $info = new CustomerInfo();
                $info->customer_id = $customer->id;
                $info->sex = $userInfo['gender'];
                $info->country = $userInfo['country'];
                $info->headimgurl = $userInfo['avatarUrl'];
                $info->name = $userInfo['nickName'];
                $info->save();
            });
        }
        return $customer;
    }

    /**
     * 验证是否成功
     */
    public function isSuccess(): bool
    {

    }

    private function getUserInfo(): array
    {
        return $this->app->encryptor->decryptData(
            $this->session['session_key'],
            $this->encryptedData['user_info']['iv'],
            $this->encryptedData['user_info']['encryptedData']
        );
    }
}